home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / tcpin.c < prev    next >
C/C++ Source or Header  |  1992-05-28  |  24KB  |  902 lines

  1. /* @(#) $Header: tcpin.c,v 1.8 92/05/28 13:50:35 deyke Exp $ */
  2.  
  3. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  4.  * the TCP specification.
  5.  *
  6.  * Copyright 1991 Phil Karn, KA9Q
  7.  */
  8. #include "global.h"
  9. #include "timer.h"
  10. #include "mbuf.h"
  11. #include "netuser.h"
  12. #include "internet.h"
  13. #include "tcp.h"
  14. #include "icmp.h"
  15. #include "iface.h"
  16. #include "ip.h"
  17.  
  18. static void update __ARGS((struct tcb *tcb,struct tcp *seg,int length));
  19. static void proc_syn __ARGS((struct tcb *tcb,int tos,struct tcp *seg));
  20. static void add_reseq __ARGS((struct tcb *tcb,int tos,struct tcp *seg,
  21.     struct mbuf *bp,int length));
  22. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  23.     struct mbuf **bp,int16 *length));
  24. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  25.     int16 *length));
  26. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  27.  
  28. /* This function is called from IP with the IP header in machine byte order,
  29.  * along with a mbuf chain pointing to the TCP header.
  30.  */
  31. void
  32. tcp_input(iface,ip,bp,rxbroadcast)
  33. struct iface *iface;    /* Incoming interface (ignored) */
  34. struct mbuf *bp;        /* Data field, if any */
  35. struct ip *ip;          /* IP header */
  36. int rxbroadcast;        /* Incoming broadcast - discard if true */
  37. {
  38.     struct tcb *ntcb;
  39.     register struct tcb *tcb;       /* TCP Protocol control block */
  40.     struct tcp seg;                 /* Local copy of segment header */
  41.     struct connection conn;         /* Local copy of addresses */
  42.     struct pseudo_header ph;        /* Pseudo-header for checksumming */
  43.     int hdrlen;                     /* Length of TCP header */
  44.     int16 length;
  45.  
  46.     if(bp == NULLBUF)
  47.         return;
  48.  
  49.     tcpInSegs++;
  50.     if(rxbroadcast){
  51.         /* Any TCP packet arriving as a broadcast is
  52.          * to be completely IGNORED!!
  53.          */
  54.         free_p(bp);
  55.         return;
  56.     }
  57.     length = ip->length - IPLEN - ip->optlen;
  58.     ph.source = ip->source;
  59.     ph.dest = ip->dest;
  60.     ph.protocol = ip->protocol;
  61.     ph.length = length;
  62.     if(cksum(&ph,bp,length) != 0){
  63.         /* Checksum failed, ignore segment completely */
  64.         tcpInErrs++;
  65.         free_p(bp);
  66.         return;
  67.     }
  68.     /* Form local copy of TCP header in host byte order */
  69.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  70.         /* TCP header is too small */
  71.         free_p(bp);
  72.         return;
  73.     }
  74.     length -= hdrlen;
  75.  
  76.     /* Fill in connection structure and find TCB */
  77.     conn.local.address = ip->dest;
  78.     conn.local.port = seg.dest;
  79.     conn.remote.address = ip->source;
  80.     conn.remote.port = seg.source;
  81.  
  82.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  83.         /* If this segment doesn't carry a SYN, reject it */
  84.         if(!seg.flags.syn){
  85.             free_p(bp);
  86.             reset(ip,&seg);
  87.             return;
  88.         }
  89.         /* See if there's a TCP_LISTEN on this socket with
  90.          * unspecified remote address and port
  91.          */
  92.         conn.remote.address = 0;
  93.         conn.remote.port = 0;
  94.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  95.             /* Nope, try unspecified local address too */
  96.             conn.local.address = 0;
  97.             if((tcb = lookup_tcb(&conn)) == NULLTCB){
  98.                 /* No LISTENs, so reject */
  99.                 free_p(bp);
  100.                 reset(ip,&seg);
  101.                 return;
  102.             }
  103.         }
  104.         /* We've found an server listen socket, so clone the TCB */
  105.         if(tcb->flags.clone){
  106.             ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  107.             ASSIGN(*ntcb,*tcb);
  108.             tcb = ntcb;
  109.             tcb->timer.arg = tcb;
  110.             /* Put on list */
  111.             tcb->next = Tcbs;
  112.             Tcbs = tcb;
  113.         }
  114.         /* Put all the socket info into the TCB */
  115.         tcb->conn.local.address = ip->dest;
  116.         tcb->conn.remote.address = ip->source;
  117.         tcb->conn.remote.port = seg.source;
  118.     }
  119.     tcb->flags.congest = ip->flags.congest;
  120.     /* Do unsynchronized-state processing (p. 65-68) */
  121.     switch(tcb->state){
  122.     case TCP_CLOSED:
  123.         free_p(bp);
  124.         reset(ip,&seg);
  125.         return;
  126.     case TCP_LISTEN:
  127.         if(seg.flags.rst){
  128.             free_p(bp);
  129.             return;
  130.         }
  131.         if(seg.flags.ack){
  132.             free_p(bp);
  133.             reset(ip,&seg);
  134.             return;
  135.         }
  136.         if(seg.flags.syn){
  137.             /* (Security check is bypassed) */
  138.             /* page 66 */
  139.             proc_syn(tcb,ip->tos,&seg);
  140.             send_syn(tcb);
  141.             setstate(tcb,TCP_SYN_RECEIVED);
  142.             if(length != 0 || seg.flags.fin) {
  143.                 /* Continue processing if there's more */
  144.                 break;
  145.             }
  146.             tcp_output(tcb);
  147.         }
  148.         free_p(bp);     /* Unlikely to get here directly */
  149.         return;
  150.     case TCP_SYN_SENT:
  151.         if(seg.flags.ack){
  152.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  153.                 free_p(bp);
  154.                 reset(ip,&seg);
  155.                 return;
  156.             }
  157.         }
  158.         if(seg.flags.rst){      /* p 67 */
  159.             if(seg.flags.ack){
  160.                 /* The ack must be acceptable since we just checked it.
  161.                  * This is how the remote side refuses connect requests.
  162.                  */
  163.                 close_self(tcb,RESET);
  164.             }
  165.             free_p(bp);
  166.             return;
  167.         }
  168.         /* (Security check skipped here) */
  169. #ifdef  PREC_CHECK      /* Turned off for compatibility with BSD */
  170.         /* Check incoming precedence; it must match if there's an ACK */
  171.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  172.             free_p(bp);
  173.             reset(ip,&seg);
  174.             return;
  175.         }
  176. #endif
  177.         if(seg.flags.syn){
  178.             proc_syn(tcb,ip->tos,&seg);
  179.             if(seg.flags.ack){
  180.                 /* Our SYN has been acked, otherwise the ACK
  181.                  * wouldn't have been valid.
  182.                  */
  183.                 update(tcb,&seg,length);
  184.                 setstate(tcb,TCP_ESTABLISHED);
  185.             } else {
  186.                 setstate(tcb,TCP_SYN_RECEIVED);
  187.             }
  188.             if(length != 0 || seg.flags.fin) {
  189.                 break;          /* Continue processing if there's more */
  190.             }
  191.             tcp_output(tcb);
  192.         } else {
  193.             free_p(bp);     /* Ignore if neither SYN or RST is set */
  194.         }
  195.         return;
  196.     }
  197.     /* We reach this point directly in any synchronized state. Note that
  198.      * if we fell through from LISTEN or SYN_SENT processing because of a
  199.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  200.      */
  201.  
  202.     /* Trim segment to fit receive window. */
  203.     if(trim(tcb,&seg,&bp,&length) == -1){
  204.         /* Segment is unacceptable */
  205.         if(!seg.flags.rst){     /* NEVER answer RSTs */
  206.             /* In SYN_RECEIVED state, answer a retransmitted SYN
  207.              * with a retransmitted SYN/ACK.
  208.              */
  209.             if(tcb->state == TCP_SYN_RECEIVED)
  210.                 tcb->snd.ptr = tcb->snd.una;
  211.             tcb->flags.force = 1;
  212.             tcp_output(tcb);
  213.         }
  214.         return;
  215.     }
  216.     /* If segment isn't the next one expected, and there's data
  217.      * or flags associated with it, put it on the resequencing
  218.      * queue, ACK it and return.
  219.      *
  220.      * Processing the ACK in an out-of-sequence segment without
  221.      * flags or data should be safe, however.
  222.      */
  223.     if(seg.seq != tcb->rcv.nxt
  224.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  225.         add_reseq(tcb,ip->tos,&seg,bp,length);
  226.         tcb->flags.force = 1;
  227.         tcp_output(tcb);
  228.         return;
  229.     }
  230.     /* This loop first processes the current segment, and then
  231.      * repeats if it can process the resequencing queue.
  232.      */
  233.     for(;;){
  234.         /* We reach this point with an acceptable segment; all data and flags
  235.          * are in the window, and the starting sequence number equals rcv.nxt
  236.          * (p. 70)
  237.          */
  238.         if(seg.flags.rst){
  239.             if(tcb->state == TCP_SYN_RECEIVED
  240.              && !tcb->flags.clone && !tcb->flags.active){
  241.                 /* Go back to listen state only if this was
  242.                  * not a cloned or active server TCB
  243.                  */
  244.                 setstate(tcb,TCP_LISTEN);
  245.             } else {
  246.                 close_self(tcb,RESET);
  247.             }
  248.             free_p(bp);
  249.             return;
  250.         }
  251.         /* (Security check skipped here) p. 71 */
  252. #ifdef  PREC_CHECK
  253.         /* Check for precedence mismatch */
  254.         if(PREC(ip->tos) != PREC(tcb->tos)){
  255.             free_p(bp);
  256.             reset(ip,&seg);
  257.             return;
  258.         }
  259. #endif
  260.         /* Check for erroneous extra SYN */
  261.         if(seg.flags.syn){
  262.             free_p(bp);
  263.             reset(ip,&seg);
  264.             return;
  265.         }
  266.         /* Check ack field p. 72 */
  267.         if(!seg.flags.ack){
  268.             free_p(bp);     /* All segments after synchronization must have ACK */
  269.             return;
  270.         }
  271.         /* Process ACK */
  272.         switch(tcb->state){
  273.         case TCP_SYN_RECEIVED:
  274.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  275.                 update(tcb,&seg,length);
  276.                 setstate(tcb,TCP_ESTABLISHED);
  277.             } else {
  278.                 free_p(bp);
  279.                 reset(ip,&seg);
  280.                 return;
  281.             }
  282.             break;
  283.         case TCP_ESTABLISHED:
  284.         case TCP_CLOSE_WAIT:
  285.             update(tcb,&seg,length);
  286.             break;
  287.         case TCP_FINWAIT1:      /* p. 73 */
  288.             update(tcb,&seg,length);
  289.             if(tcb->sndcnt == 0){
  290.                 /* Our FIN is acknowledged */
  291.                 setstate(tcb,TCP_FINWAIT2);
  292.             }
  293.             break;
  294.         case TCP_FINWAIT2:
  295.             update(tcb,&seg,length);
  296.             break;
  297.         case TCP_CLOSING:
  298.             update(tcb,&seg,length);
  299.             if(tcb->sndcnt == 0){
  300.                 /* Our FIN is acknowledged */
  301.                 setstate(tcb,TCP_TIME_WAIT);
  302.                 set_timer(&tcb->timer,MSL2*1000L);
  303.                 start_timer(&tcb->timer);
  304.             }
  305.             break;
  306.         case TCP_LAST_ACK:
  307.             update(tcb,&seg,length);
  308.             if(tcb->sndcnt == 0){
  309.                 /* Our FIN is acknowledged, close connection */
  310.                 close_self(tcb,NORMAL);
  311.                 return;
  312.             }
  313.             break;
  314.         case TCP_TIME_WAIT:
  315.             start_timer(&tcb->timer);
  316.             break;
  317.         }
  318.  
  319.         /* (URGent bit processing skipped here) */
  320.  
  321.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  322.         if(length != 0){
  323.             switch(tcb->state){
  324.             case TCP_SYN_RECEIVED:
  325.             case TCP_ESTABLISHED:
  326.             case TCP_FINWAIT1:
  327.             case TCP_FINWAIT2:
  328.                 /* Place on receive queue */
  329.                 append(&tcb->rcvq,bp);
  330.                 tcb->rcvcnt += length;
  331.                 tcb->rcv.nxt += length;
  332.                 tcb->rcv.wnd -= length;
  333.                 tcb->flags.force = 1;
  334.                 /* Notify user */
  335.                 if(tcb->r_upcall)
  336.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  337.                 break;
  338.             default:
  339.                 /* Ignore segment text */
  340.                 free_p(bp);
  341.                 break;
  342.             }
  343.         }
  344.         /* process FIN bit (p 75) */
  345.         if(seg.flags.fin){
  346.             tcb->flags.force = 1;   /* Always respond with an ACK */
  347.  
  348.             switch(tcb->state){
  349.             case TCP_SYN_RECEIVED:
  350.             case TCP_ESTABLISHED:
  351.                 tcb->rcv.nxt++;
  352.                 setstate(tcb,TCP_CLOSE_WAIT);
  353.                 break;
  354.             case TCP_FINWAIT1:
  355.                 tcb->rcv.nxt++;
  356.                 if(tcb->sndcnt == 0){
  357.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  358.                     setstate(tcb,TCP_TIME_WAIT);
  359.                     set_timer(&tcb->timer,MSL2*1000L);
  360.                     start_timer(&tcb->timer);
  361.                 } else {
  362.                     setstate(tcb,TCP_CLOSING);
  363.                 }
  364.                 break;
  365.             case TCP_FINWAIT2:
  366.                 tcb->rcv.nxt++;
  367.                 setstate(tcb,TCP_TIME_WAIT);
  368.                 set_timer(&tcb->timer,MSL2*1000L);
  369.                 start_timer(&tcb->timer);
  370.                 break;
  371.             case TCP_CLOSE_WAIT:
  372.             case TCP_CLOSING:
  373.             case TCP_LAST_ACK:
  374.                 break;          /* Ignore */
  375.             case TCP_TIME_WAIT:     /* p 76 */
  376.                 start_timer(&tcb->timer);
  377.                 break;
  378.             }
  379.             /* Call the client again so he can see EOF */
  380.             if(tcb->r_upcall)
  381.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  382.         }
  383.         /* Scan the resequencing queue, looking for a segment we can handle,
  384.          * and freeing all those that are now obsolete.
  385.          */
  386.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  387.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  388.             if(trim(tcb,&seg,&bp,&length) == 0)
  389.                 goto gotone;
  390.             /* Segment is an old one; trim has freed it */
  391.         }
  392.         break;
  393. gotone: ;
  394.     }
  395.     tcp_output(tcb);        /* Send any necessary ack */
  396. }
  397.  
  398. /* Process an incoming ICMP response */
  399. void
  400. tcp_icmp(icsource,source,dest,type,code,bpp)
  401. int32 icsource;                 /* Sender of ICMP message (not used) */
  402. int32 source;                   /* Original IP datagram source (i.e. us) */
  403. int32 dest;                     /* Original IP datagram dest (i.e., them) */
  404. char type,code;                 /* ICMP error codes */
  405. struct mbuf **bpp;              /* First 8 bytes of TCP header */
  406. {
  407.     struct tcp seg;
  408.     struct connection conn;
  409.     register struct tcb *tcb;
  410.  
  411.     /* Extract the socket info from the returned TCP header fragment
  412.      * Note that since this is a datagram we sent, the source fields
  413.      * refer to the local side.
  414.      */
  415.     ntohtcp(&seg,bpp);
  416.     conn.local.port = seg.source;
  417.     conn.remote.port = seg.dest;
  418.     conn.local.address = source;
  419.     conn.remote.address = dest;
  420.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  421.         return; /* Unknown connection, ignore */
  422.  
  423.     /* Verify that the sequence number in the returned segment corresponds
  424.      * to something currently unacknowledged. If not, it can safely
  425.      * be ignored.
  426.      */
  427.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  428.         return;
  429.  
  430.     /* Destination Unreachable and Time Exceeded messages never kill a
  431.      * connection; the info is merely saved for future reference.
  432.      */
  433.     switch(uchar(type)){
  434.     case ICMP_DEST_UNREACH:
  435.     case ICMP_TIME_EXCEED:
  436.         tcb->type = type;
  437.         tcb->code = code;
  438.         break;
  439.     case ICMP_QUENCH:
  440.         /* Source quench; cut the congestion window in half,
  441.          * but don't let it go below one packet
  442.          */
  443.         tcb->cwind /= 2;
  444.         tcb->cwind = max(tcb->mss,tcb->cwind);
  445.         break;
  446.     }
  447. }
  448. /* Send an acceptable reset (RST) response for this segment
  449.  * The RST reply is composed in place on the input segment
  450.  */
  451. void
  452. reset(ip,seg)
  453. struct ip *ip;                  /* Offending IP header */
  454. register struct tcp *seg;       /* Offending TCP header */
  455. {
  456.     struct mbuf *hbp;
  457.     struct pseudo_header ph;
  458.     int16 tmp;
  459.  
  460.     if(seg->flags.rst)
  461.         return; /* Never send an RST in response to an RST */
  462.  
  463.     /* Compose the RST IP pseudo-header, swapping addresses */
  464.     ph.source = ip->dest;
  465.     ph.dest = ip->source;
  466.     ph.protocol = TCP_PTCL;
  467.     ph.length = TCPLEN;
  468.  
  469.     /* Swap port numbers */
  470.     tmp = seg->source;
  471.     seg->source = seg->dest;
  472.     seg->dest = tmp;
  473.  
  474.     if(seg->flags.ack){
  475.         /* This reset is being sent to clear a half-open connection.
  476.          * Set the sequence number of the RST to the incoming ACK
  477.          * so it will be acceptable.
  478.          */
  479.         seg->flags.ack = 0;
  480.         seg->seq = seg->ack;
  481.         seg->ack = 0;
  482.     } else {
  483.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  484.          * so we have to "acknowledge" their SYN.
  485.          */
  486.         seg->flags.ack = 1;
  487.         seg->ack = seg->seq;
  488.         seg->seq = 0;
  489.         if(seg->flags.syn)
  490.             seg->ack++;
  491.     }
  492.     /* Set remaining parts of packet */
  493.     seg->flags.urg = 0;
  494.     seg->flags.psh = 0;
  495.     seg->flags.rst = 1;
  496.     seg->flags.syn = 0;
  497.     seg->flags.fin = 0;
  498.     seg->wnd = 0;
  499.     seg->up = 0;
  500.     seg->mss = 0;
  501.     seg->optlen = 0;
  502.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  503.         return;
  504.     /* Ship it out (note swap of addresses) */
  505.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  506.     tcpOutRsts++;
  507. }
  508.  
  509. /* Process an incoming acknowledgement and window indication.
  510.  * From page 72.
  511.  */
  512. static void
  513. update(tcb,seg,length)
  514. register struct tcb *tcb;
  515. register struct tcp *seg;
  516. int16 length;
  517. {
  518.     int16 acked;
  519.     int16 expand;
  520.  
  521.     acked = 0;
  522.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  523.         tcb->flags.force = 1;   /* Acks something not yet sent */
  524.         return;
  525.     }
  526.     /* Decide if we need to do a window update.
  527.      * This is always checked whenever a legal ACK is received,
  528.      * even if it doesn't actually acknowledge anything,
  529.      * because it might be a spontaneous window reopening.
  530.      */
  531.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1)
  532.      && seq_ge(seg->ack,tcb->snd.wl2))){
  533.         /* If the window had been closed, crank back the
  534.          * send pointer so we'll immediately resume transmission.
  535.          * Otherwise we'd have to wait until the next probe.
  536.          */
  537.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  538.             tcb->snd.ptr = tcb->snd.una;
  539.         tcb->snd.wnd = seg->wnd;
  540.         tcb->snd.wl1 = seg->seq;
  541.         tcb->snd.wl2 = seg->ack;
  542.     }
  543.     /* See if anything new is being acknowledged */
  544.     if(!seq_gt(seg->ack,tcb->snd.una)){
  545.         if(seg->ack != tcb->snd.una)
  546.             return; /* Old ack, ignore */
  547.  
  548.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  549.             return; /* Nothing acked, but there is data */
  550.  
  551.         /* Van Jacobson "fast recovery" code */
  552.         if(++tcb->dupacks == TCPDUPACKS){
  553.             /* We've had a burst of do-nothing acks, so
  554.              * we almost certainly lost a packet.
  555.              * Resend it now to avoid a timeout. (This is
  556.              * Van Jacobson's 'quick recovery' algorithm.)
  557.              */
  558.             int32 ptrsave;
  559.  
  560.             /* Knock the threshold down just as though
  561.              * this were a timeout, since we've had
  562.              * network congestion.
  563.              */
  564.             tcb->ssthresh = tcb->cwind/2;
  565.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  566.  
  567.             /* Manipulate the machinery in tcp_output() to
  568.              * retransmit just the missing packet
  569.              */
  570.             ptrsave = tcb->snd.ptr;
  571.             tcb->snd.ptr = tcb->snd.una;
  572.             tcb->cwind = tcb->mss;
  573.             tcp_output(tcb);
  574.             tcb->snd.ptr = ptrsave;
  575.  
  576.             /* "Inflate" the congestion window, pretending as
  577.              * though the duplicate acks were normally acking
  578.              * the packets beyond the one that was lost.
  579.              */
  580.             tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  581.         } else if(tcb->dupacks > TCPDUPACKS){
  582.             /* Continue to inflate the congestion window
  583.              * until the acks finally get "unstuck".
  584.              */
  585.             tcb->cwind += tcb->mss;
  586.         }
  587.         return;
  588.     }
  589.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  590.         /* The acks have finally gotten "unstuck". So now we
  591.          * can "deflate" the congestion window, i.e. take it
  592.          * back down to where it would be after slow start
  593.          * finishes.
  594.          */
  595.         tcb->cwind = tcb->ssthresh;
  596.     }
  597.     tcb->dupacks = 0;
  598.  
  599.     /* We're here, so the ACK must have actually acked something */
  600.     acked = seg->ack - tcb->snd.una;
  601.  
  602.     /* Expand congestion window if not already at limit and if
  603.      * this packet wasn't retransmitted
  604.      */
  605.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  606.         if(tcb->cwind < tcb->ssthresh){
  607.             /* Still doing slow start/CUTE, expand by amount acked */
  608.             expand = min(acked,tcb->mss);
  609.         } else {
  610.             /* Steady-state test of extra path capacity */
  611.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  612.         }
  613.         /* Guard against arithmetic overflow */
  614.         if(tcb->cwind + expand < tcb->cwind)
  615.             expand = MAXINT16 - tcb->cwind;
  616.  
  617.         /* Don't expand beyond the offered window */
  618.         if(tcb->cwind + expand > tcb->snd.wnd)
  619.             expand = tcb->snd.wnd - tcb->cwind;
  620.  
  621.         if(expand != 0){
  622. #ifdef  notdef
  623.             /* Kick up the mean deviation estimate to prevent
  624.              * unnecessary retransmission should we already be
  625.              * bandwidth limited
  626.              */
  627.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  628. #endif
  629.             tcb->cwind += expand;
  630.         }
  631.     }
  632.     /* Round trip time estimation */
  633.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  634.         /* A timed sequence number has been acked */
  635.         tcb->flags.rtt_run = 0;
  636.         if(!(tcb->flags.retran)){
  637.             int32 rtt;      /* measured round trip time */
  638.             int32 abserr;   /* abs(rtt - srtt) */
  639.  
  640.             /* This packet was sent only once and now
  641.              * it's been acked, so process the round trip time
  642.              */
  643.             rtt = msclock() - tcb->rtt_time;
  644.  
  645.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  646.             /* Run SRTT and MDEV integrators, with rounding */
  647.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  648.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  649.  
  650.             rtt_add(tcb->conn.remote.address,rtt);
  651.             /* Reset the backoff level */
  652.             tcb->backoff = 0;
  653.         }
  654.     }
  655.     tcb->sndcnt -= acked;   /* Update virtual byte count on snd queue */
  656.     tcb->snd.una = seg->ack;
  657.  
  658.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  659.     if(!(tcb->flags.synack)){
  660.         tcb->flags.synack = 1;
  661.         acked--;        /* One less byte to pull from real snd queue */
  662.     }
  663.     /* Remove acknowledged bytes from the send queue and update the
  664.      * unacknowledged pointer. If a FIN is being acked,
  665.      * pullup won't be able to remove it from the queue, but that
  666.      * causes no harm.
  667.      */
  668.     pullup(&tcb->sndq,NULLCHAR,acked);
  669.  
  670.     /* Stop retransmission timer, but restart it if there is still
  671.      * unacknowledged data. If there is no more unacked data,
  672.      * the transmitter has gone at least momentarily idle, so
  673.      * record the time for the VJ restart-slowstart rule.
  674.      */
  675.     stop_timer(&tcb->timer);
  676.     if(tcb->snd.una != tcb->snd.nxt)
  677.         start_timer(&tcb->timer);
  678.     else
  679.         tcb->lastactive = msclock();
  680.  
  681.     /* If retransmissions have been occurring, make sure the
  682.      * send pointer doesn't repeat ancient history
  683.      */
  684.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  685.         tcb->snd.ptr = tcb->snd.una;
  686.  
  687.     /* Clear the retransmission flag since the oldest
  688.      * unacknowledged segment (the only one that is ever retransmitted)
  689.      * has now been acked.
  690.      */
  691.     tcb->flags.retran = 0;
  692.  
  693.     /* If outgoing data was acked, notify the user so he can send more
  694.      * unless we've already sent a FIN.
  695.      */
  696.     if(acked != 0 && tcb->t_upcall
  697.      && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)
  698.      && tcb->window > tcb->sndcnt){
  699.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  700.     }
  701. }
  702.  
  703. /* Determine if the given sequence number is in our receiver window.
  704.  * NB: must not be used when window is closed!
  705.  */
  706. static
  707. int
  708. in_window(tcb,seq)
  709. struct tcb *tcb;
  710. int32 seq;
  711. {
  712.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  713. }
  714.  
  715. /* Process an incoming SYN */
  716. static void
  717. proc_syn(tcb,tos,seg)
  718. register struct tcb *tcb;
  719. char tos;
  720. struct tcp *seg;
  721. {
  722.     int16 mtu;
  723.     struct tcp_rtt *tp;
  724.  
  725.     tcb->flags.force = 1;   /* Always send a response */
  726.  
  727.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  728.      * SND.WND are initialized here since it's possible for the
  729.      * window update routine in update() to fail depending on the
  730.      * IRS if they are left unitialized.
  731.      */
  732.     /* Check incoming precedence and increase if higher */
  733.     if(PREC(tos) > PREC(tcb->tos))
  734.         tcb->tos = tos;
  735.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  736.     tcb->snd.wl1 = tcb->irs = seg->seq;
  737.     tcb->snd.wnd = seg->wnd;
  738.     if(seg->mss != 0)
  739.         tcb->mss = seg->mss;
  740.     /* Check the MTU of the interface we'll use to reach this guy
  741.      * and lower the MSS so that unnecessary fragmentation won't occur
  742.      */
  743.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  744.         /* Allow space for the TCP and IP headers */
  745.         mtu -= TCPLEN + IPLEN;
  746.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  747.     }
  748.     /* See if there's round-trip time experience */
  749.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  750.         tcb->srtt = tp->srtt;
  751.         tcb->mdev = tp->mdev;
  752.     }
  753. }
  754.  
  755. /* Generate an initial sequence number and put a SYN on the send queue */
  756. void
  757. send_syn(tcb)
  758. register struct tcb *tcb;
  759. {
  760.     tcb->iss = geniss();
  761.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  762.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  763.     tcb->sndcnt++;
  764.     tcb->flags.force = 1;
  765. }
  766.  
  767. /* Add an entry to the resequencing queue in the proper place */
  768. static void
  769. add_reseq(tcb,tos,seg,bp,length)
  770. struct tcb *tcb;
  771. char tos;
  772. struct tcp *seg;
  773. struct mbuf *bp;
  774. int16 length;
  775. {
  776.     register struct reseq *rp,*rp1;
  777.  
  778.     /* Allocate reassembly descriptor */
  779.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  780.         /* No space, toss on floor */
  781.         free_p(bp);
  782.         return;
  783.     }
  784.     ASSIGN(rp->seg,*seg);
  785.     rp->tos = tos;
  786.     rp->bp = bp;
  787.     rp->length = length;
  788.  
  789.     /* Place on reassembly list sorting by starting seq number */
  790.     rp1 = tcb->reseq;
  791.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  792.         /* Either the list is empty, or we're less than all other
  793.          * entries; insert at beginning.
  794.          */
  795.         rp->next = rp1;
  796.         tcb->reseq = rp;
  797.     } else {
  798.         /* Find the last entry less than us */
  799.         for(;;){
  800.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  801.                 /* We belong just after this one */
  802.                 rp->next = rp1->next;
  803.                 rp1->next = rp;
  804.                 break;
  805.             }
  806.             rp1 = rp1->next;
  807.         }
  808.     }
  809. }
  810.  
  811. /* Fetch the first entry off the resequencing queue */
  812. static void
  813. get_reseq(tcb,tos,seg,bp,length)
  814. register struct tcb *tcb;
  815. char *tos;
  816. struct tcp *seg;
  817. struct mbuf **bp;
  818. int16 *length;
  819. {
  820.     register struct reseq *rp;
  821.  
  822.     if((rp = tcb->reseq) == NULLRESEQ)
  823.         return;
  824.  
  825.     tcb->reseq = rp->next;
  826.  
  827.     *tos = rp->tos;
  828.     ASSIGN(*seg,rp->seg);
  829.     *bp = rp->bp;
  830.     *length = rp->length;
  831.     free((char *)rp);
  832. }
  833.  
  834. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  835.  * unacceptable.
  836.  */
  837. static int
  838. trim(tcb,seg,bpp,length)
  839. register struct tcb *tcb;
  840. register struct tcp *seg;
  841. struct mbuf **bpp;
  842. int16 *length;
  843. {
  844.     long dupcnt,excess;
  845.     int16 len;              /* Segment length including flags */
  846.     char accept = 0;
  847.  
  848.     len = *length;
  849.     if(seg->flags.syn)
  850.         len++;
  851.     if(seg->flags.fin)
  852.         len++;
  853.  
  854.     /* Acceptability tests */
  855.     if(tcb->rcv.wnd == 0){
  856.         /* Only in-order, zero-length segments are acceptable when
  857.          * our window is closed.
  858.          */
  859.         if(seg->seq == tcb->rcv.nxt && len == 0){
  860.             return 0;       /* Acceptable, no trimming needed */
  861.         }
  862.     } else {
  863.         /* Some part of the segment must be in the window */
  864.         if(in_window(tcb,seg->seq)){
  865.             accept++;       /* Beginning is */
  866.         } else if(len != 0){
  867.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  868.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  869.                 accept++;
  870.             }
  871.         }
  872.     }
  873.     if(!accept){
  874.         tcb->rerecv += len;     /* Assume all of it was a duplicate */
  875.         free_p(*bpp);
  876.         return -1;
  877.     }
  878.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  879.         tcb->rerecv += dupcnt;
  880.         /* Trim off SYN if present */
  881.         if(seg->flags.syn){
  882.             /* SYN is before first data byte */
  883.             seg->flags.syn = 0;
  884.             seg->seq++;
  885.             dupcnt--;
  886.         }
  887.         if(dupcnt > 0){
  888.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  889.             seg->seq += dupcnt;
  890.             *length -= dupcnt;
  891.         }
  892.     }
  893.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  894.         tcb->rerecv += excess;
  895.         /* Trim right edge */
  896.         *length -= excess;
  897.         trim_mbuf(bpp,*length);
  898.         seg->flags.fin = 0;     /* FIN follows last data byte */
  899.     }
  900.     return 0;
  901. }
  902.